package com.ken.common.core.exception;

import com.ken.entity.base.protocol.R;
import com.ken.entity.base.util.RCode;
import com.ken.entity.base.util.ResultUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * SpringBoot全局异常处理
 */
@Slf4j
@RestControllerAdvice
@Order(Ordered.LOWEST_PRECEDENCE)
public class GlobalException {


    /**
     * 参数校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(BindException.class)
    public R validException(BindException e){
        //获得校验异常信息
        BindingResult bindingResult = e.getBindingResult();
        Set<String> collect = bindingResult.getAllErrors().stream()
                .map(objectError -> objectError.getDefaultMessage())
                .collect(Collectors.toSet());
        return ResultUtils.createFail(RCode.PARAM_INVALID);
    }

    /**
     * 捕获到自定义异常
     * @return
     */
    @ExceptionHandler(ServerException.class)
    public R serverException(ServerException e){
        log.error("[Global-Exception] - 发生业务异常！", e);
        return new ResultUtils().create(e.getCode(), e.getMsg(), null);
    }

    /**
     * 全局异常处理
     * @return
     */
    @ExceptionHandler
    public R globalException(Throwable t){
        log.error("[Global-Exception] - 发生全局异常！");
        try {
            //获得请求的URL
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
            String url = request.getRequestURL().toString();
            log.error("[Global-Exception] - 请求的url - {}", url);

            //获得请求参数
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!CollectionUtils.isEmpty(parameterMap)) {
                for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                    log.error("[Global-Exception] - 请求参数 - {}:{}", entry.getKey(), Arrays.toString(entry.getValue()));
                }
            }
        } catch (Exception e) {
        } finally {
            //记录异常信息
            log.error("[Global-Exception] - 异常信息", t);
        }
        //返回信息
        return ResultUtils.createFail(RCode.FAIL);
    }
}
